package com.qidian.mes.log.aop;

import com.qidian.mes.log.annotation.OptionLogAnnotation;
import com.qidian.mes.log.mapper.LogMapper;
import com.qidian.mes.log.pojo.OptionLog;
import com.qidian.mes.util.JSONTools;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

/**
 * @Author 戴着假发的程序员
 * @Company 起点编程
 * @Time 2023/10/26 9:38
 * @Description
 */
@Aspect
public class LogAspect {

    // 注入SQLSessionFactory
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    // 拦截所有有OptionLogAnnotation注解的方法
    @Around(value="@annotation(com.qidian.mes.log.annotation.OptionLogAnnotation)")
    public Object log(ProceedingJoinPoint joinPoint){

        Object returnValue = null;
        // 执行方法
        try {
            returnValue = joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }

        // 方法的请求参数
        Object[] args = joinPoint.getArgs();
        // 获取方法上方的注解
        Object target = joinPoint.getTarget();// 方法所在类的对象
        String methodName = joinPoint.getSignature().getName();// 获取方法的名字
        System.out.println("方法名：" + methodName);
        // 获取参数列表类型
        Class [] paramsClass = new Class[args.length];
        HttpServletRequest request = null;
        for (int i = 0;i < args.length;i ++){
            if(Arrays.asList(args[i].getClass().getInterfaces()).contains(HttpServletRequest.class)){
                request = (HttpServletRequest) args[i];
                paramsClass[i] = HttpServletRequest.class;
            }else {
                paramsClass[i] = args[i].getClass();
            }
        }
        // 获取方法对象本身
        try {
            Method method = target.getClass().getMethod(methodName, paramsClass);
            // 获取方法上方的注解
            OptionLogAnnotation annotation = method.getAnnotation(OptionLogAnnotation.class);
            if(annotation != null){// 要记录日志
                OptionLog optionLog = new OptionLog();
                optionLog.setUserId(1L);// 用户编号先写死
                optionLog.setOptionModule(annotation.optionModule());
                optionLog.setOptionType(annotation.optionType().toString());
                optionLog.setOptionTime(new Date());
                // 将参数转换为JSON，request对象无法转换
                for (int i = 0;i < args.length;i ++){
                    if(Arrays.asList(args[i].getClass().getInterfaces()).contains(HttpServletRequest.class)){
                        args[i] = "request";//  排除request
                    }
                }
                optionLog.setRequestParam(JSONTools.object2json(args));
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                PostMapping postMapping = method.getAnnotation(PostMapping.class);
                PutMapping putMapping = method.getAnnotation(PutMapping.class);
                DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
                GetMapping getMapping = method.getAnnotation(GetMapping.class);
                if(requestMapping != null){
                    optionLog.setRequestMethod(requestMapping.method().toString());
                    optionLog.setRequestPath(Arrays.toString(requestMapping.value()));
                }else if(postMapping != null){
                    optionLog.setRequestMethod("POST");
                    optionLog.setRequestPath(Arrays.toString(postMapping.value()));
                }else if(putMapping != null){
                    optionLog.setRequestMethod("PUT");
                    optionLog.setRequestPath(Arrays.toString(putMapping.value()));
                }else if(deleteMapping != null){
                    optionLog.setRequestMethod("DELETE");
                    optionLog.setRequestPath(Arrays.toString(deleteMapping.value()));
                }else if(getMapping != null){
                    optionLog.setRequestMethod("GET");
                    optionLog.setRequestPath(Arrays.toString(getMapping.value()));
                }
                //  判断请求方法参数中是否有request对象
                if(request != null) {
                    optionLog.setRequestAddress(request.getRemoteAddr());
                }
                optionLog.setRequestResult(JSONTools.object2json(returnValue));

                System.out.println(optionLog);
                // 将optionLong存入数据库
                LogMapper logMapper = sqlSessionFactory.openSession(true).getMapper(LogMapper.class);
                logMapper.saveOption(optionLog);
            }
        } catch (NoSuchMethodException e) {
            System.out.println(e);
//            throw new RuntimeException(e);
        }
        // 返回返回值
        return returnValue;
    }

}
